๐Ÿน.dev
[BOJ 3654] Lํผ์ฆ2024๋…„ 3์›” 19์ผ ์ƒ์„ฑ(2024๋…„ 3์›” 19์ผ ์ˆ˜์ •)์•Œ๊ณ ๋ฆฌ์ฆ˜2-SAT

๋ฌธ์ œ ์†Œ๊ฐœ

๋ฌธ์ œ ๋งํฌ : https://boj.kr/3654

Tier : Diamond IV

Tag : 2-SAT

3์นธ์„ ์ฐจ์ง€ํ•˜๋Š” L๋ชจ์–‘์˜ ํผ์ฆ ์กฐ๊ฐ์ด ์žˆ๋‹ค. ์ค‘๊ฐ„์€ ๊ฒ€์€ ์ƒ‰์ด๋ฉฐ, ๋‚˜๋จธ์ง€ ๋‘ ์นธ์€ ํ•˜์–€ ์ƒ‰์ด๋‹ค.

๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งˆ๋‹ค N * M ํฌ๊ธฐ์˜ ํŒจํ„ด์ด ์ฃผ์–ด์ง€๋Š”๋ฐ,

์šฐ๋ฆฌ๋Š” ํ•ด๋‹น ํผ์ฆ ์กฐ๊ฐ์„ ์ ์ ˆํžˆ ๋†“์•˜์„ ๋•Œ ํŒจํ„ด์„ ์˜จ์ „ํžˆ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

์ด๋•Œ, ํผ์ฆ ์กฐ๊ฐ์€ ํšŒ์ „ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๊ฒน์น  ์ˆ˜ ์—†๋‹ค.

ํ’€์ด

1. ์ผ๋ฐ˜์ ์ธ ๊ทœ์น™ ์ฐพ๊ธฐ

ํŒจํ„ด ๋‚ด์˜

2. ์œ ํšจํ•˜์ง€ ์•Š์€ ์ผ€์ด์Šค ์ฐพ๊ธฐ

ํŒจํ„ด ๋‚ด์˜

3. ์œ„์˜ ๊ทœ์น™์„ ํ† ๋Œ€๋กœ 2-SAT์œผ๋กœ ๋ชจ๋ธ๋งํ•˜๊ธฐ

์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ด ๊ทœ์น™์„ ๋…ผ๋ฆฌ์‹์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

ํŠน์ • ๋ณ€์ˆ˜ a, b, c, ...์— ๋Œ€ํ•ด,

  1. (a v b) : a ๋˜๋Š” b๊ฐ€ true์—ฌ์•ผ ์„ฑ๋ฆฝ
  2. (a v a) : a๊ฐ€ true์—ฌ์•ผ ์„ฑ๋ฆฝ
  3. (!a v !b) ^ (!a v !c) ^ ... : a, b, c, ... ์ค‘ 1๊ฐœ ์ดํ•˜๋งŒ true์—ฌ์•ผ ์„ฑ๋ฆฝ
  4. (!a v b) ^ (a v !b) ^ (!a v c) ^ (a v !c) ^ ... : a, b, c, ... ๋ชจ๋‘ true์ด๊ฑฐ๋‚˜ false์—ฌ์•ผ ์„ฑ๋ฆฝ

๋“ฑ์˜ ๋ฐฉ์‹์œผ๋กœ ๋…ผ๋ฆฌ์‹์„ ๋ชจ๋ธ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งน์  1

์ด๋ฅผ ์ด์šฉํ•˜์—ฌ **๊ทœ์น™ (b)**์˜ ์ผ๋ถ€๋ฅผ ์ถฉ์กฑํ•˜์ง€๋งŒ, ๊ฒ€์€ ์ƒ‰ ์นธ ์ „๋ถ€ ํฌํ•จ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋„ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜, ์ด ๋งน์ ์€ ๊ทœ์น™ (c)๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด, ์ €๋Ÿฐ ์ƒํ™ฉ์ด ์˜ฌ ๊ฒฝ์šฐ ํ•˜์–€ ์ƒ‰ ์นธ์ด ๋‚จ๊ฒŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋งน์  2

ํŠน์ •ํ•œ ๊ฒ€์€ ์ƒ‰ ์นธ์— ๋Œ€ํ•ด, ์ฃผ๋ณ€์˜ ํ•˜์–€ ์ƒ‰ ์นธ์ด ๊ฐ€๋กœ ์„ธ๋กœ๋‹น ํ•˜๋‚˜์”ฉ๋งŒ ๋ถ™์–ด์•ผ ํ•˜๋Š” **์กฐ๊ฑด (a)**๋Š” ์–ด๋–ป๊ฒŒ ์ถฉ์กฑ์‹œ์ผœ์•ผ ํ• ๊นŒ?

์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ณ€์ˆ˜ ์„ค์ •์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฒ€์€ ์ƒ‰ ์นธ์— ์ธ์ ‘ํ•œ ๊ฐ€๋กœ ์นธ ์ค‘, ์™ผ์ชฝ์— ์กด์žฌํ•˜๋Š” ํ•˜์–€ ์นธ์„ false, ์˜ค๋ฅธ์ชฝ์— ์กด์žฌํ•˜๋Š” ํ•˜์–€ ์นธ์„ true๋กœ ๊ฐ„์ฃผํ•˜์—ฌ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•œ๋‹ค.

์„ธ๋กœ ์นธ์˜ ๊ฒฝ์šฐ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค.

ํŠน์ • ๋ณ€์ˆ˜๋Š” ๋ฌด์กฐ๊ฑด true ๋˜๋Š” false์ด๋ฏ€๋กœ, ๋…ผ๋ฆฌ์‹์„ ์ด์šฉํ•˜์ง€ ์•Š๊ณ  ๋ณ€์ˆ˜ ์„ค์ •๋งŒ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‚˜๋จธ์ง€ ๊ทœ์น™ (d), (e)์˜ ๊ฒฝ์šฐ ํŠน์ • ์นธ์— ๊ฒน์น˜๋Š” ๋ณ€์ˆ˜๋ฅผ ๋ชจ๋‘ ๋ชฐ์•„๋„ฃ์–ด (b)๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ๊ฐ™์ด ์ฒดํฌํ•˜๋ฉด ๋œ๋‹ค.

์ฝ”๋“œ

solution.cpp
1#include <bits/stdc++.h>
2#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr)
3
4#define BLANK 0
5#define BLACK 1
6#define WHITE 2
7#define MAX 1010101
8
9using namespace std;
10
11vector<int> nodes[502][502], graph[MAX];
12stack<int> candidate;
13
14int discovered[MAX], sccIDs[MAX];
15int puzzle[502][502];
16
17int nodeID, sccID;
18int N, M, whiteID;
19bool possible = true;
20
21// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งˆ๋‹ค ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
22void init() {
23 for (int i = 0; i < 502; i++) {
24 for (int j = 0; j < 502; j++) {
25 puzzle[i][j] = BLANK;
26 nodes[i][j] = vector<int>();
27 }
28 }
29
30 for (int i = 0; i < MAX; i++) {
31 graph[i] = vector<int>();
32 }
33
34 candidate = stack<int>();
35 possible = true;
36
37 nodeID = sccID = 1;
38 whiteID = 0;
39
40 memset(discovered, 0, sizeof discovered);
41 memset(sccIDs, 0, sizeof sccIDs);
42}
43
44// SCC๋ฅผ ํ˜•์„ฑํ•œ๋‹ค.
45int createSCC(int node) {
46 int id = discovered[node] = nodeID++;
47 candidate.push(node);
48
49 for (auto next : graph[node]) {
50 if (!discovered[next])
51 id = min(id, createSCC(next));
52
53 else if (!sccIDs[next])
54 id = min(id, discovered[next]);
55 }
56
57 if (id == discovered[node]) {
58 while (true) {
59 int top = candidate.top();
60 candidate.pop();
61
62 sccIDs[top] = sccID;
63
64 if (top == node)
65 break;
66 }
67
68 sccID++;
69 }
70
71 return id;
72}
73
74// ํŒจํ„ด ๋งค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ง€ ์ฒดํฌํ•œ๋‹ค.
75void check() {
76 for (int i = 0; i < whiteID; i++) {
77 if (!discovered[i]) createSCC(i);
78 }
79
80 for (int i = 0; i < whiteID; i += 4) {
81 int left = i, right = i + 1, top = i + 2, bottom = i + 3;
82
83 if ((sccIDs[left] == sccIDs[right]) || (sccIDs[top] == sccIDs[bottom])) {
84 possible = false;
85 return;
86 }
87 }
88}
89
90// ํŒจํ„ด ์ •๋ณด๋ฅผ ํ† ๋Œ€๋กœ 2-SAT ๊ทธ๋ž˜ํ”„๋ฅผ ๋ชจ๋ธ๋งํ•œ๋‹ค.
91void analyse() {
92 // 1. B ๊ธฐ์ค€
93 for (int i = 1; i <= N; i++) {
94 for (int j = 1; j <= M; j++) {
95 if (puzzle[i][j] != BLACK) continue;
96
97 // 1-1. Horizontal
98 int left = whiteID, right = whiteID + 1;
99
100 if (puzzle[i][j - 1] == WHITE && puzzle[i][j + 1] == WHITE) {
101 nodes[i][j - 1].push_back(left);
102 nodes[i][j + 1].push_back(right);
103 }
104
105 else if (puzzle[i][j - 1] != WHITE && puzzle[i][j + 1] == WHITE) {
106 nodes[i][j + 1].push_back(right);
107
108 // ์˜ค๋ฅธ์ชฝ W๊ฐ€ ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
109 graph[left].push_back(right);
110 }
111
112 else if (puzzle[i][j - 1] == WHITE && puzzle[i][j + 1] != WHITE) {
113 nodes[i][j - 1].push_back(left);
114
115 // ์™ผ์ชฝ W๊ฐ€ ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
116 graph[right].push_back(left);
117 }
118
119 // ๋‘˜ ๋‹ค ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ Lํผ์ฆ์„ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.
120 else {
121 possible = false;
122 return;
123 }
124
125 // 1-2. Vertical
126 int top = whiteID + 2, bottom = whiteID + 3;
127
128 if (puzzle[i - 1][j] == WHITE && puzzle[i + 1][j] == WHITE) {
129 nodes[i - 1][j].push_back(top);
130 nodes[i + 1][j].push_back(bottom);
131 }
132
133 else if (puzzle[i - 1][j] != WHITE && puzzle[i + 1][j] == WHITE) {
134 nodes[i + 1][j].push_back(bottom);
135
136 // ์•„๋ž˜์ชฝ W๊ฐ€ ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
137 graph[top].push_back(bottom);
138 }
139
140 else if (puzzle[i - 1][j] == WHITE && puzzle[i + 1][j] != WHITE) {
141 nodes[i - 1][j].push_back(top);
142
143 // ์œ„์ชฝ W๊ฐ€ ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
144 graph[bottom].push_back(top);
145 }
146
147 // ๋‘˜ ๋‹ค ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ Lํผ์ฆ์„ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.
148 else {
149 possible = false;
150 return;
151 }
152
153 whiteID += 4;
154 }
155 }
156
157 // 2. W ๊ธฐ์ค€
158 for (int i = 1; i <= N; i++) {
159 for (int j = 1; j <= M; j++) {
160 if (puzzle[i][j] != WHITE) continue;
161
162 // W๊ฐ€ ์–ด๋–ค B์—๋„ ์ธ์ ‘ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ Lํผ์ฆ์„ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.
163 if (nodes[i][j].empty()) {
164 possible = false;
165 return;
166 }
167
168 int U = (int) nodes[i][j].size();
169
170 // 2-1. B๊ฐ€ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ, ์ด W๋Š” ํ•ด๋‹น B๋ฅผ ๋ฌด์กฐ๊ฑด ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.
171 if (U == 1) {
172 int v = nodes[i][j][0];
173 graph[v ^ 1].push_back(v);
174
175 continue;
176 }
177
178 // 2-2. ์ด๋“ค ์ค‘ ๋‘ ๊ฐœ ์ด์ƒ์„ ๋งŒ์กฑ์‹œํ‚ค์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
179 for (int x = 0; x < U - 1; x++) {
180 int vx = nodes[i][j][x];
181
182 for (int y = x + 1; y < U; y++) {
183 int vy = nodes[i][j][y];
184
185 // (!x1 v !y1) = y1 -> x2, x1 -> y2
186 graph[vy].push_back(vx ^ 1);
187 graph[vx].push_back(vy ^ 1);
188 }
189 }
190 }
191 }
192}
193
194int main() {
195 FAST_IO;
196 int T; cin >> T;
197
198 while (T--) {
199 init();
200
201 // 1. ์ž…๋ ฅ ๋ฐ›๊ธฐ
202 cin >> N >> M;
203
204 int white = 0, black = 0;
205
206 for (int i = 1; i <= N; i++) {
207 for (int j = 1; j <= M; j++) {
208 char c; cin >> c;
209
210 if (c == 'B') { black++; puzzle[i][j] = BLACK; }
211 if (c == 'W') { white++; puzzle[i][j] = WHITE; }
212 if (c == '.') { puzzle[i][j] = BLANK; }
213 }
214 }
215
216 if (white != black << 1) {
217 cout << "NO" << "\n";
218 continue;
219 }
220
221 // 2. ํŒจํ„ด์„ ๊ทธ๋ž˜ํ”„ํ™”
222 analyse();
223
224 if (!possible) {
225 cout << "NO" << "\n";
226 continue;
227 }
228
229 // 3. ํŒจํ„ด ๋งค์นญ ์ฒดํฌ
230 check();
231
232 cout << (possible ? "YES" : "NO") << "\n";
233 }
234
235 return 0;
236}
237
solution.cpp
1#include <bits/stdc++.h>
2#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr)
3
4#define BLANK 0
5#define BLACK 1
6#define WHITE 2
7#define MAX 1010101
8
9using namespace std;
10
11vector<int> nodes[502][502], graph[MAX];
12stack<int> candidate;
13
14int discovered[MAX], sccIDs[MAX];
15int puzzle[502][502];
16
17int nodeID, sccID;
18int N, M, whiteID;
19bool possible = true;
20
21// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งˆ๋‹ค ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
22void init() {
23 for (int i = 0; i < 502; i++) {
24 for (int j = 0; j < 502; j++) {
25 puzzle[i][j] = BLANK;
26 nodes[i][j] = vector<int>();
27 }
28 }
29
30 for (int i = 0; i < MAX; i++) {
31 graph[i] = vector<int>();
32 }
33
34 candidate = stack<int>();
35 possible = true;
36
37 nodeID = sccID = 1;
38 whiteID = 0;
39
40 memset(discovered, 0, sizeof discovered);
41 memset(sccIDs, 0, sizeof sccIDs);
42}
43
44// SCC๋ฅผ ํ˜•์„ฑํ•œ๋‹ค.
45int createSCC(int node) {
46 int id = discovered[node] = nodeID++;
47 candidate.push(node);
48
49 for (auto next : graph[node]) {
50 if (!discovered[next])
51 id = min(id, createSCC(next));
52
53 else if (!sccIDs[next])
54 id = min(id, discovered[next]);
55 }
56
57 if (id == discovered[node]) {
58 while (true) {
59 int top = candidate.top();
60 candidate.pop();
61
62 sccIDs[top] = sccID;
63
64 if (top == node)
65 break;
66 }
67
68 sccID++;
69 }
70
71 return id;
72}
73
74// ํŒจํ„ด ๋งค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ง€ ์ฒดํฌํ•œ๋‹ค.
75void check() {
76 for (int i = 0; i < whiteID; i++) {
77 if (!discovered[i]) createSCC(i);
78 }
79
80 for (int i = 0; i < whiteID; i += 4) {
81 int left = i, right = i + 1, top = i + 2, bottom = i + 3;
82
83 if ((sccIDs[left] == sccIDs[right]) || (sccIDs[top] == sccIDs[bottom])) {
84 possible = false;
85 return;
86 }
87 }
88}
89
90// ํŒจํ„ด ์ •๋ณด๋ฅผ ํ† ๋Œ€๋กœ 2-SAT ๊ทธ๋ž˜ํ”„๋ฅผ ๋ชจ๋ธ๋งํ•œ๋‹ค.
91void analyse() {
92 // 1. B ๊ธฐ์ค€
93 for (int i = 1; i <= N; i++) {
94 for (int j = 1; j <= M; j++) {
95 if (puzzle[i][j] != BLACK) continue;
96
97 // 1-1. Horizontal
98 int left = whiteID, right = whiteID + 1;
99
100 if (puzzle[i][j - 1] == WHITE && puzzle[i][j + 1] == WHITE) {
101 nodes[i][j - 1].push_back(left);
102 nodes[i][j + 1].push_back(right);
103 }
104
105 else if (puzzle[i][j - 1] != WHITE && puzzle[i][j + 1] == WHITE) {
106 nodes[i][j + 1].push_back(right);
107
108 // ์˜ค๋ฅธ์ชฝ W๊ฐ€ ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
109 graph[left].push_back(right);
110 }
111
112 else if (puzzle[i][j - 1] == WHITE && puzzle[i][j + 1] != WHITE) {
113 nodes[i][j - 1].push_back(left);
114
115 // ์™ผ์ชฝ W๊ฐ€ ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
116 graph[right].push_back(left);
117 }
118
119 // ๋‘˜ ๋‹ค ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ Lํผ์ฆ์„ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.
120 else {
121 possible = false;
122 return;
123 }
124
125 // 1-2. Vertical
126 int top = whiteID + 2, bottom = whiteID + 3;
127
128 if (puzzle[i - 1][j] == WHITE && puzzle[i + 1][j] == WHITE) {
129 nodes[i - 1][j].push_back(top);
130 nodes[i + 1][j].push_back(bottom);
131 }
132
133 else if (puzzle[i - 1][j] != WHITE && puzzle[i + 1][j] == WHITE) {
134 nodes[i + 1][j].push_back(bottom);
135
136 // ์•„๋ž˜์ชฝ W๊ฐ€ ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
137 graph[top].push_back(bottom);
138 }
139
140 else if (puzzle[i - 1][j] == WHITE && puzzle[i + 1][j] != WHITE) {
141 nodes[i - 1][j].push_back(top);
142
143 // ์œ„์ชฝ W๊ฐ€ ๋ฌด์กฐ๊ฑด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
144 graph[bottom].push_back(top);
145 }
146
147 // ๋‘˜ ๋‹ค ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ Lํผ์ฆ์„ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.
148 else {
149 possible = false;
150 return;
151 }
152
153 whiteID += 4;
154 }
155 }
156
157 // 2. W ๊ธฐ์ค€
158 for (int i = 1; i <= N; i++) {
159 for (int j = 1; j <= M; j++) {
160 if (puzzle[i][j] != WHITE) continue;
161
162 // W๊ฐ€ ์–ด๋–ค B์—๋„ ์ธ์ ‘ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ Lํผ์ฆ์„ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.
163 if (nodes[i][j].empty()) {
164 possible = false;
165 return;
166 }
167
168 int U = (int) nodes[i][j].size();
169
170 // 2-1. B๊ฐ€ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ, ์ด W๋Š” ํ•ด๋‹น B๋ฅผ ๋ฌด์กฐ๊ฑด ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.
171 if (U == 1) {
172 int v = nodes[i][j][0];
173 graph[v ^ 1].push_back(v);
174
175 continue;
176 }
177
178 // 2-2. ์ด๋“ค ์ค‘ ๋‘ ๊ฐœ ์ด์ƒ์„ ๋งŒ์กฑ์‹œํ‚ค์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
179 for (int x = 0; x < U - 1; x++) {
180 int vx = nodes[i][j][x];
181
182 for (int y = x + 1; y < U; y++) {
183 int vy = nodes[i][j][y];
184
185 // (!x1 v !y1) = y1 -> x2, x1 -> y2
186 graph[vy].push_back(vx ^ 1);
187 graph[vx].push_back(vy ^ 1);
188 }
189 }
190 }
191 }
192}
193
194int main() {
195 FAST_IO;
196 int T; cin >> T;
197
198 while (T--) {
199 init();
200
201 // 1. ์ž…๋ ฅ ๋ฐ›๊ธฐ
202 cin >> N >> M;
203
204 int white = 0, black = 0;
205
206 for (int i = 1; i <= N; i++) {
207 for (int j = 1; j <= M; j++) {
208 char c; cin >> c;
209
210 if (c == 'B') { black++; puzzle[i][j] = BLACK; }
211 if (c == 'W') { white++; puzzle[i][j] = WHITE; }
212 if (c == '.') { puzzle[i][j] = BLANK; }
213 }
214 }
215
216 if (white != black << 1) {
217 cout << "NO" << "\n";
218 continue;
219 }
220
221 // 2. ํŒจํ„ด์„ ๊ทธ๋ž˜ํ”„ํ™”
222 analyse();
223
224 if (!possible) {
225 cout << "NO" << "\n";
226 continue;
227 }
228
229 // 3. ํŒจํ„ด ๋งค์นญ ์ฒดํฌ
230 check();
231
232 cout << (possible ? "YES" : "NO") << "\n";
233 }
234
235 return 0;
236}
237